package com.whz.mlc.provider.proxy;

import com.google.common.base.Stopwatch;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInvocation;

import java.util.concurrent.TimeUnit;

/**
 * @author whz
 * 2021/8/13
 */
public interface ProxyFilter {
    ProxyFilter DEFAULT_FILTER = new DefaultProxyFilter();

    /**
     * 过滤对象和方法,是否满足指定的aop条件
     *
     * @param invocation MethodInvocation
     * @return true 需要AOP
     */
    boolean filter(MethodInvocation invocation);


    /**
     * 在方法执行之前
     *
     * @param invocation MethodInvocation
     */
    void onBefore(MethodInvocation invocation);

    /**
     * 在方法执行之后
     *
     * @param invocation MethodInvocation
     */
    void onAfter(MethodInvocation invocation, Object returnValue);

    /**
     * 异常回调
     *
     * @param throwable 异常
     */
    void onError(Throwable throwable);


    @Slf4j
    class DefaultProxyFilter implements ProxyFilter {

        Stopwatch start;

        @Override
        public boolean filter(MethodInvocation invocation) {
            return true;
        }

        @Override
        public void onBefore(MethodInvocation invocation) {
            start = Stopwatch.createStarted();
        }

        @Override
        public void onAfter(MethodInvocation invocation, Object returnValue) {
            long dur = start.elapsed(TimeUnit.MILLISECONDS);
            if (dur > 300) {
                log.info("拦截的缓存方法 : {}.{},cost:{}ms", className(invocation), invocation.getMethod().getName(), dur);
            }
        }

        private String className(MethodInvocation invocation) {
            return invocation.getMethod().getDeclaringClass().getSimpleName();
        }

        @Override
        public void onError(Throwable throwable) {
            log.error("error.", throwable);
        }
    }
}